import Clipboard from 'clipboard'
import {Base64} from 'js-base64'
import { throttle , upperFirst, cloneDeep} from 'lodash'
import {getUUID as v1} from '@/utils/util'

const menuAll = [
  {key: 'lock', icon: 'icon-lock', label: '锁定'},
  {key: 'unlock', icon: 'icon-unlock', label: '解锁'},
  {key: 'delete', icon: 'icon-delete', label: '删除'},
  {key: 'invisible', icon: 'icon-invisible', label: '隐藏'},
  {key: 'visible', icon: 'icon-visible', label: '显示'},
  {key: 'unGroup', icon: 'icon-spread', label: '解除分组'},
  {divider: true},
  {key: 'copy', icon: 'icon-copy', label: '复制'},
  {key: 'copyCode', icon: 'icon-code', label: '复制代码'},
  {divider: true},
  {key: 'top', icon: 'icon-double-arrow-up', label: '置顶'},
  {key: 'bottom', icon: 'icon-double-arrow-down', label: '置底'},
  {key: 'up', icon: 'icon-mono-top', label: '上移'},
  {key: 'down', icon: 'icon-mono-bottom', label: '下移'}
]

const containerMenu = [
  {key: 'paste', icon: 'icon-paste', label: '粘贴'},
  {key: 'clear', icon: 'icon-copy', label: '清空剪贴板'},
]

export default {
  data() {
    return {
      mousePosition: {
        startX: 0,
        startY: 0,
        x: 0,
        y: 0
      },
      rightSelect: {
        target: null,
        index: -1
      },
      isSelect: false // 是否正在进行框选
    }
  },
  methods: {
    onContainerContextmenu(e) {
      e.stopPropagation()
      e.preventDefault()

      this.menus = containerMenu
      this.$refs.contextMenu.show({x: e.clientX, y: e.clientY})
    },
    // 右键菜单
    onContextmenu(e, item, index) {
      console.info(e)
      e.stopPropagation()
      e.preventDefault()

      const cacheChoicesKeys = Object.keys(this.cacheChoices)

      if(cacheChoicesKeys.length > 1) {
        const menus = [
          {key: 'deleteMultiple', icon: 'icon-delete', label: '选中删除'},
          {key: 'group', icon: 'icon-combine', label: '创建分组'},
          {key: 'lockMultiple', icon: 'icon-lock', label: '选中锁定'}
        ]

        this.menus = menus
      } else {
        if(!item.status) {
          item.status = {
            hide: false,
            lock: false
          }
        }

        const exclude = []
        // 隐藏/显示
        if(item.status.hide) {
          exclude.push('invisible')
        } else {
          exclude.push('visible')
        }
        // 锁定/解锁
        if(item.status.lock) {
          exclude.push('lock')
        } else {
          exclude.push('unlock')
        }
        if(!item.isGroup) {
          exclude.push('unGroup')
        }

        if(!e.altKey) {
          exclude.push('copyCode')
        }


        const menus = menuAll.filter(o => !exclude.includes(o.key))
        this.menus = menus

        this.rightSelect = {
          target: item,
          index: index
        }
      }

      this.$refs.contextMenu.show({x: e.clientX, y: e.clientY})
    },
    // 菜单点击
    onMenuClick(item) {
      const name = upperFirst(item.key)
      this['onMenu' + name]()
    },
    // 锁定
    onMenuLock() {
      const target = this.rightSelect.target
      this.lockTarget(target)
    },
    lockTarget(target) {
      target.status.lock = true
      // 被选中，取消选中
      if(this.cacheChoices[target.id]) {
        delete this.cacheChoices[target.id]
        delete this.cacheChoicesFixed[target.id]
      }
      // 取消配置项
      if(this.currentCpt.id === target.id) {
        this.currentCpt = {}
        this.currentCptIndex = -1
      }
    },
    // 解锁
    onMenuUnlock() {
      this.rightSelect.target.status.lock = false
    },
    // 删除
    onMenuDelete() {
      this.cacheComponents.splice(this.rightSelect.index, 1)
    },
    // 隐藏
    onMenuInvisible() {
      const target = this.rightSelect.target
      this.hideTarget(target)
    },
    hideTarget(target) {
      target.status.hide = true
      // 被选中，取消选中
      if(this.cacheChoices[target.id]) {
        delete this.cacheChoices[target.id]
        delete this.cacheChoicesFixed[target.id]
      }
      // 取消配置项
      if(this.currentCpt.id === target.id) {
        this.currentCpt = {}
        this.currentCptIndex = -1
      }
    },
    // 显示
    onMenuVisible() {
      const target = this.rightSelect.target
      target.status.hide = false
    },
    // 上移一层
    onMenuUp() {
      const index = this.rightSelect.index
      if(index !== 0) {
        this.cacheComponents[index] = this.cacheComponents.splice(
          index - 1,
          1,
          this.cacheComponents[index]
        )[0];
      } else {
        this.cacheComponents.push(this.cacheComponents.shift())
      }

    },
    // 下移一层
    onMenuDown() {
      const index = this.rightSelect.index
      if (index != this.cacheComponents.length - 1) {
        this.cacheComponents[index] = this.cacheComponents.splice(
          index + 1,
          1,
          this.cacheComponents[index]
        )[0];
      } else {
        this.cacheComponents.unshift(this.cacheComponents.splice(index, 1)[0]);
      }
    },
    // 置顶
    onMenuTop() {
      const index = this.rightSelect.index
      if (index !== 0) {
        this.cacheComponents.unshift(this.cacheComponents.splice(index, 1)[0]);
      }
    },
    // 置底
    onMenuBottom() {
      const index = this.rightSelect.index
      if (index + 1 < this.cacheComponents.length) {
        const temp = this.cacheComponents.splice(index, 1)[0];
        this.cacheComponents.push(temp);
      }
    },
    // 选中删除
    onMenuDeleteMultiple() {
      const cacheChoicesKeys = Object.keys(this.cacheChoices)
      cacheChoicesKeys.forEach(key => {
        this.removeComponentById(key)
      })
    },
    // 选中锁定
    onMenuLockMultiple() {
      const cacheChoicesKeys = Object.keys(this.cacheChoices)
      cacheChoicesKeys.forEach(key => {
        const finded = this.cacheComponents.find(o => o.id === key)
        finded.status.lock = true
      })
    },
    // 创建分组
    onMenuGroup() {
      const cacheChoicesKeys = Object.keys(this.cacheChoices)
      if(cacheChoicesKeys.length < 2) {
        return
      }

      const groupData = {
        id: v1(),
        isGroup: true,
        collapsed: false,
        cptRotate: 0,
        key: 'group',
        cptTitle: '分组',
        cptX: 0,
        cptY: 0,
        cptWidth: 0,
        cptHeight: 0,
        groupList: [],
        scaleX: 1,
        scaleY: 1,
        status: {
          lock: false,
          hide: false
        }
      }
      // 记录整体坐标
      const groupAttr = {
        l: this.designData.scaleX,
        t: this.designData.scaleY,
        r: 0,
        b: 0
      }
      const targetList = []
      const newSelectIds = []
      cacheChoicesKeys.forEach(id => {
        const findIndex = this.findTargetIndex(id)

        if(findIndex !== -1 && this.cacheComponents[findIndex].isGroup) {
          this.setUnGroup([id], groupList => {
            groupList.forEach(item => {
              this.addComponent(item)
              newSelectIds.push(item.id)
            })
          })
        } else if(findIndex !== -1) {
          newSelectIds.push(id)
        }
      })

      newSelectIds.forEach(id => {
        // 获取目标数据并从 list 中移除 (成组后不可再次成组, 断言处理)
        const item = this.cacheComponents.splice(this.findTargetIndex(id), 1)[0]
        const {cptX, cptY, cptWidth, cptHeight} = item
        const { l, t, r, b } = groupAttr

        // 左
        groupAttr.l  = l > cptX ? cptX : l
        // 上
        groupAttr.t = t > cptY ? cptY : t
        // 宽
        groupAttr.r = r < cptX + cptWidth ? cptX + cptWidth : r
        // 高
        groupAttr.b = b < cptY + cptHeight ? cptY + cptHeight : b

        targetList.push(item)
      })

      // 设置子组件的位置
      targetList.forEach((item) => {
        item.cptX = item.cptX - groupAttr.l
        item.cptY = item.cptY - groupAttr.t
        groupData.groupList.push(item)
      })

      groupData.cptX = groupAttr.l
      groupData.cptY = groupAttr.t
      groupData.cptWidth = groupAttr.r - groupAttr.l
      groupData.cptHeight = groupAttr.b - groupAttr.t
      groupData.originWidth = groupData.cptWidth
      groupData.originHeight = groupData.cptHeight

      this.addComponent(groupData)

      this.outBlur()
    },
    // 解除分组
    onMenuUnGroup() {
      const target = this.rightSelect.target
      this.setUnGroup([target.id])
    },
    setUnGroup(ids, callback) {
      const targetIndex = this.findTargetIndex(ids[0])

      const unGroup = (_targetIndex) => {
        const targetGroup = this.cacheComponents[_targetIndex]
        if(!targetGroup.isGroup) {
          return
        }

        // 分离组件并还原位置属性
        targetGroup.groupList.forEach(item => {
          item.cptX = item.cptX + targetGroup.cptX
          item.cptY = item.cptY + targetGroup.cptY

          if(!callback) {
            this.addComponent(item)
          }
        })

        if(callback) {
          callback(targetGroup.groupList)
        }

        this.removeComponentById(targetGroup.id)
      }

      // 判断目标是否为分组父级
      if (targetIndex !== -1) {
        unGroup(targetIndex)
      }
    },
    // 复制组件代码
    onMenuCopyCode() {
      const target = this.rightSelect.target
      const clone = cloneDeep(target)
      // 重新生成id
      clone.id = v1()
      if(clone.isGroup) {
        clone.groupList.forEach(item => {
          item.id = v1()
        })
      }
      const code = 'TM_DESIGNER:' + JSON.stringify(clone)
      const str = Base64.encode(code)
      Clipboard.copy(str)
      this.$message.success('复制成功!')
    },
    // 复制组件
    onMenuCopy() {
      const target = this.rightSelect.target
      const clone = cloneDeep(target)
      // 重新生成id
      clone.id = v1()
      if(clone.isGroup) {
        clone.groupList.forEach(item => {
          item.id = v1()
        })
      }
      this.copyRecord = clone
      // const str = "" + JSON.stringify(clone)
      // Clipboard.copy(JSON.stringify(target))
      // this.$message.success('复制成功!')
    },
    // 粘贴组件
    onMenuPaste() {
      if(this.copyRecord) {
        this.addComponent(this.copyRecord)
      }
    },
    // 清空剪贴板
    onMenuClear() {
      this.copyRecord = null
    },
    findTargetIndex(id) {
      return this.cacheComponents.findIndex( o => o.id === id)
    },
    removeComponentById(id) {
      const index = this.cacheComponents.findIndex(o => o.id === id)
      this.cacheComponents.splice(index,1)
    },
    addComponent(comp) {
      this.cacheComponents.push(comp)
    },
    // 框选或背景点击
    onMousedownSelect(e) {
      const startOffsetX = e.offsetX
      const startOffsetY = e.offsetY
      const startScreenX = e.screenX
      const startScreenY = e.screenY

      this.mousePosition.startX = startOffsetX
      this.mousePosition.startY =startOffsetY

      const scale = this.containerScale

      const mousemove = throttle((moveEvent) => {
        const currX = startOffsetX + moveEvent.screenX - startScreenX
        const currY = startOffsetY + moveEvent.screenY - startScreenY

        this.mousePosition.x = currX
        this.mousePosition.y = currY
        this.isSelect = true
      }, 1)

      const mouseup = (moveEvent) => {

        this.isSelect = false // 框选完成
        // 清空框选位置
        this.mousePosition = {
          x: 0,
          y: 0,
          startX: 0,
          startY: 0
        }

        document.removeEventListener('mousemove', mousemove)
        document.removeEventListener('mouseup', mouseup)

        const currX = startOffsetX + moveEvent.screenX - startScreenX
        const currY = startOffsetY + moveEvent.screenY - startScreenY

        // 计算框选的左上角和右下角
        const selectAttr = {
          // 左上角
          x1: 0,
          y1: 0,
          // 右下角
          x2: 0,
          y2: 0
        }

        let hasSelected = false

        if (currX > startOffsetX && currY > startOffsetY) {
          // 右下方向
          selectAttr.x1 = startOffsetX
          selectAttr.y1 = startOffsetY
          selectAttr.x2 = Math.round(startOffsetX + (moveEvent.screenX - startScreenX) / scale)
          selectAttr.y2 = Math.round(startOffsetY + (moveEvent.screenY - startScreenY) / scale)
        } else if (currX > startOffsetX && currY < startOffsetY) {
          // 右上方向
          selectAttr.x1 = startOffsetX
          selectAttr.y1 = Math.round(startOffsetY - (startScreenY - moveEvent.screenY) / scale)
          selectAttr.x2 = Math.round(startOffsetX + (moveEvent.screenX - startScreenX) / scale)
          selectAttr.y2 = startOffsetY
        } else if (currX < startOffsetX && currY > startOffsetY) {
          selectAttr.x1 = Math.round(startOffsetX - (startScreenX - moveEvent.screenX) / scale)
          selectAttr.y1 = startOffsetY
          selectAttr.x2 = startOffsetX
          selectAttr.y2 = Math.round(startOffsetY + (moveEvent.screenY - startScreenY) / scale)
          // 左下方向
        } else {
          // 左上方向
          selectAttr.x1 = Math.round(startOffsetX - (startScreenX - moveEvent.screenX) / scale)
          selectAttr.y1 = Math.round(startOffsetY - (startScreenY - moveEvent.screenY) / scale)
          selectAttr.x2 = startOffsetX
          selectAttr.y2 = startOffsetY
        }

        this.cacheComponents.forEach(item => {

          const {cptWidth, cptHeight, cptX, cptY} = item
          const targetAttr = {
            // 左上角
            x1: cptX,
            y1: cptY,
            // 右下角
            x2: cptX + cptWidth,
            y2: cptY + cptHeight
          }

          // 全包含则选中
          if (
            targetAttr.x1 - selectAttr.x1 >= 0 &&
            targetAttr.y1 - selectAttr.y1 >= 0 &&
            targetAttr.x2 - selectAttr.x2 <= 0 &&
            targetAttr.y2 - selectAttr.y2 <= 0 &&
            !item.status.lock &&
            !item.status.hide
          ) {
            hasSelected = true
            this.cacheChoices[item.id] = item
            this.cacheChoicesFixed[item.id]=JSON.parse(JSON.stringify(item))
          }
        })
        // 没有框选中，相当于失去焦点
        if(!hasSelected) {
          this.outBlur()
        }
      }

      document.addEventListener('mousemove', mousemove)
      document.addEventListener('mouseup', mouseup)
    },
    onInnerKeyDown(e) {
      e.stopPropagation()
      e.preventDefault()
      console.info(e)

    }
  }
}
